home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 14 / Example 14.1 / mesh.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-07-01  |  5.4 KB  |  221 lines

  1. #include "mesh.h"
  2.  
  3. const DWORD ObjectVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
  4.  
  5. MESH::MESH()
  6. {
  7.     m_pDevice = NULL;
  8.     m_pMesh = NULL;
  9. }
  10.  
  11. MESH::MESH(char fName[], IDirect3DDevice9* Dev)
  12. {
  13.     m_pDevice = Dev;
  14.     m_pMesh = NULL;
  15.     Load(fName, m_pDevice);
  16. }
  17.  
  18. MESH::~MESH()
  19. {
  20.     Release();
  21. }
  22.  
  23. HRESULT MESH::Load(char fName[], IDirect3DDevice9* Dev)
  24. {
  25.     m_pDevice = Dev;
  26.  
  27.     //Set m_white material
  28.     m_white.Ambient = m_white.Specular = m_white.Diffuse  = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  29.     m_white.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
  30.     m_white.Power = 1.0f;
  31.  
  32.     Release();
  33.  
  34.     //Load new mesh
  35.     ID3DXBuffer * adjacencyBfr = NULL;
  36.     ID3DXBuffer * materialBfr = NULL;
  37.     DWORD noMaterials = NULL;
  38.  
  39.     if(FAILED(D3DXLoadMeshFromX(fName, D3DXMESH_MANAGED, m_pDevice, &adjacencyBfr, &materialBfr, NULL, &noMaterials, &m_pMesh)))
  40.         return E_FAIL;
  41.  
  42.     D3DXMATERIAL *mtrls = (D3DXMATERIAL*)materialBfr->GetBufferPointer();
  43.  
  44.     for(int i=0;i<noMaterials;i++)
  45.     {
  46.         m_materials.push_back(mtrls[i].MatD3D);
  47.  
  48.         if(mtrls[i].pTextureFilename != NULL)
  49.         {
  50.             char textureFileName[90];
  51.             strcpy(textureFileName, "meshes/");
  52.             strcat(textureFileName, mtrls[i].pTextureFilename);
  53.             IDirect3DTexture9 * newTexture = NULL;
  54.             D3DXCreateTextureFromFile(m_pDevice, textureFileName, &newTexture);            
  55.             m_textures.push_back(newTexture);
  56.         }
  57.         else m_textures.push_back(NULL);
  58.     }
  59.  
  60.     m_pMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE,
  61.                             (DWORD*)adjacencyBfr->GetBufferPointer(), NULL, NULL, NULL);
  62.  
  63.     adjacencyBfr->Release();
  64.     materialBfr->Release();
  65.  
  66.     return S_OK;
  67. }
  68.  
  69. void MESH::Render()
  70. {
  71.     for(int i=0;i<m_materials.size();i++)
  72.     {    
  73.         if(m_textures[i] != NULL)m_pDevice->SetMaterial(&m_white);
  74.         else m_pDevice->SetMaterial(&m_materials[i]);
  75.         m_pDevice->SetTexture(0,m_textures[i]);
  76.         m_pMesh->DrawSubset(i);
  77.     }    
  78. }
  79.  
  80. void MESH::Render(float prc)
  81. {
  82.     //Calculate the end subset to render
  83.     int end = m_materials.size() * prc;
  84.  
  85.     for(int i=0;i<m_materials.size() && i < end;i++)
  86.     {        
  87.         if(m_textures[i] != NULL)m_pDevice->SetMaterial(&m_white);
  88.         else m_pDevice->SetMaterial(&m_materials[i]);
  89.         m_pDevice->SetTexture(0,m_textures[i]);
  90.         m_pMesh->DrawSubset(i);
  91.     }
  92. }
  93.  
  94. void MESH::Release()
  95. {
  96.     //Clear old mesh...
  97.     if(m_pMesh != NULL)
  98.     {
  99.         m_pMesh->Release();
  100.         m_pMesh = NULL;
  101.     }
  102.  
  103.     //Clear textures and materials
  104.     for(int i=0;i<m_textures.size();i++)
  105.         if(m_textures[i] != NULL)
  106.             m_textures[i]->Release();
  107.  
  108.     m_textures.clear();
  109.     m_materials.clear();    
  110. }
  111.  
  112. MESHINSTANCE::MESHINSTANCE()
  113. {
  114.     m_pMesh = NULL;
  115.     m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  116.     m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
  117. }
  118.  
  119. MESHINSTANCE::MESHINSTANCE(MESH *meshPtr)
  120. {
  121.     m_pMesh = meshPtr;
  122.     m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  123.     m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
  124. }
  125.  
  126. D3DXMATRIX MESHINSTANCE::GetWorldMatrix()
  127. {
  128.     D3DXMATRIX p, r, s;
  129.     D3DXMatrixTranslation(&p, m_pos.x, m_pos.y, m_pos.z);
  130.     D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
  131.     D3DXMatrixScaling(&s, m_sca.x, m_sca.y, m_sca.z);
  132.  
  133.     D3DXMATRIX world = s * r * p;
  134.     return world;
  135. }
  136.  
  137. void MESHINSTANCE::Render()
  138. {
  139.     if(m_pMesh != NULL)
  140.     {
  141.         m_pMesh->m_pDevice->SetTransform(D3DTS_WORLD, &GetWorldMatrix());
  142.         m_pMesh->Render();
  143.     }
  144. }
  145.  
  146. void MESHINSTANCE::Render(float prc)
  147. {
  148.     if(m_pMesh != NULL)
  149.     {
  150.         m_pMesh->m_pDevice->SetTransform(D3DTS_WORLD, &GetWorldMatrix());
  151.         m_pMesh->Render(prc);
  152.     }
  153. }
  154.  
  155. BBOX MESHINSTANCE::GetBoundingBox()
  156. {
  157.     if(m_pMesh == NULL || m_pMesh->m_pMesh == NULL)return BBOX();
  158.     
  159.     if(m_pMesh->m_pMesh->GetFVF() != ObjectVertex::FVF)        // XYZ and NORMAL and UV
  160.         return BBOX();
  161.  
  162.     BBOX bBox(D3DXVECTOR3(-10000.0f, -10000.0f, -10000.0f),
  163.               D3DXVECTOR3(10000.0f, 10000.0f, 10000.0f));
  164.     D3DXMATRIX World = GetWorldMatrix();
  165.  
  166.     //Lock vertex buffer of the object
  167.     ObjectVertex* vertexBuffer = NULL;
  168.     m_pMesh->m_pMesh->LockVertexBuffer(0,(void**)&vertexBuffer);
  169.  
  170.     //For each vertex in the mesh
  171.     for(int i=0;i<m_pMesh->m_pMesh->GetNumVertices();i++)
  172.     {
  173.         //Transform vertex to world space using the MESHINSTANCE
  174.         //world matrix, i.e. the position, rotation and scale
  175.         D3DXVECTOR3 pos;
  176.         D3DXVec3TransformCoord(&pos, &vertexBuffer[i]._pos, &World);
  177.  
  178.         // Check if the vertex is outside the bounds
  179.         // if so, then update the bounding volume
  180.         if(pos.x < bBox.min.x)bBox.min.x = pos.x;
  181.         if(pos.x > bBox.max.x)bBox.max.x = pos.x;
  182.         if(pos.y < bBox.min.y)bBox.min.y = pos.y;
  183.         if(pos.y > bBox.max.y)bBox.max.y = pos.y;
  184.         if(pos.z < bBox.min.z)bBox.min.z = pos.z;
  185.         if(pos.z > bBox.max.z)bBox.max.z = pos.z;
  186.     }
  187.  
  188.     m_pMesh->m_pMesh->UnlockVertexBuffer();
  189.  
  190.     return bBox;
  191. }
  192.  
  193. BSPHERE MESHINSTANCE::GetBoundingSphere()
  194. {
  195.     if(m_pMesh == NULL || m_pMesh->m_pMesh == NULL)return BSPHERE();
  196.     if(m_pMesh->m_pMesh->GetFVF() != ObjectVertex::FVF)        // XYZ and NORMAL and UV
  197.         return BSPHERE();
  198.  
  199.     BBOX bBox = GetBoundingBox();
  200.     BSPHERE bSphere;
  201.     D3DXMATRIX World = GetWorldMatrix();
  202.     bSphere.center = (bBox.max + bBox.min) / 2.0f;
  203.  
  204.     ObjectVertex* vertexBuffer = NULL;
  205.     m_pMesh->m_pMesh->LockVertexBuffer(0,(void**)&vertexBuffer);
  206.  
  207.     //Get radius
  208.     for(int i=0;i<m_pMesh->m_pMesh->GetNumVertices();i++)
  209.     {
  210.         D3DXVECTOR3 pos;
  211.         D3DXVec3TransformCoord(&pos, &vertexBuffer[i]._pos, &World);
  212.  
  213.         float l = D3DXVec3Length(&(pos - bSphere.center));
  214.         if(l > bSphere.radius)
  215.             bSphere.radius = l;
  216.     }
  217.  
  218.     m_pMesh->m_pMesh->UnlockVertexBuffer();
  219.  
  220.     return bSphere;
  221. }